package com.ibeeking.found.uaa.c.service.impl;

import com.ibeeking.found.auth.api.common.dto.MemberLoginDTO;
import com.ibeeking.found.auth.api.common.query.LoginAuthQuery;
import com.ibeeking.found.auth.api.common.query.OpenIdQuery;
import com.ibeeking.found.auth.api.feign.MemberLoginClient;
import com.ibeeking.found.common.config.feign.MsgFeignClient;
import com.ibeeking.found.common.config.secret.RsaConfig;
import com.ibeeking.found.common.enums.LoginModeEnum;
import com.ibeeking.found.common.enums.LoginRoleEnum;
import com.ibeeking.found.common.enums.PublishStatusEnum;
import com.ibeeking.found.uaa.c.model.ClientUserDetails;
import com.ibeeking.found.uaa.c.model.WxAppletModel;
import com.ibeeking.found.uaa.c.model.WxSmsCodeModel;
import com.ibeeking.found.uaa.c.service.IClientUserDetailsService;
import com.ibeeking.nematos.constants.enums.LogConstant;
import com.ibeeking.nematos.exception.AuthorizationException;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.ibeeking.nematos.utils.result.ResponseResult;
import org.apache.logging.log4j.ThreadContext;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author ibeeking
 */
@Service
public class ClientUserDetailsServiceImpl implements IClientUserDetailsService {

    @Resource
    private MemberLoginClient memberLoginClient;
    @Resource
    private RsaConfig rsaConfig;
    @Resource
    private MsgFeignClient msgClient;

    @Override
    public ClientUserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return new ClientUserDetails();
    }

    @Override
    public ClientUserDetails loadUserByPhoneAndSmsCode(WxSmsCodeModel wxSmsCodeModel) {
        String tenantId = ThreadContext.get(LogConstant.TENANT_ID);
        if (StringUtils.isBlank(tenantId)) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "请选择小程序后登录");
        }
        if (StringUtils.isBlank(wxSmsCodeModel.getOpenId())) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "登录用户名必填");
        }
        if (StringUtils.isBlank(wxSmsCodeModel.getPhone())) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "手机号不能为空");
        }
        if (StringUtils.isBlank(wxSmsCodeModel.getCode())) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "手机验证码不能为空");
        }
        if (StringUtils.isBlank(wxSmsCodeModel.getKey())) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "验证码标识不能为空");
        }
        ResponseResult<Boolean> responseResult = msgClient.checkVerificationCode(wxSmsCodeModel.getKey(), wxSmsCodeModel.getPhone(), wxSmsCodeModel.getCode());
        if (null == responseResult || !responseResult.getData()) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "验证码错误或已过期");
        }
        LoginAuthQuery query = new LoginAuthQuery();
        query.setLoginMode(LoginModeEnum.WX_MA.getCode());
        query.setOpenId(wxSmsCodeModel.getOpenId());
        query.setMobile(wxSmsCodeModel.getPhone());
        ResponseResult<MemberLoginDTO> result = memberLoginClient.queryLoginMemberByMobileOpenId(query);
        if (null == result || null == result.getData()) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "会员不存在，请注册后再试");
        }

        return queryMember(tenantId, result.getData());
    }

    @Override
    public ClientUserDetails wxAppletsLogin(WxAppletModel wxAppletModel) {
        String tenantId = ThreadContext.get(LogConstant.TENANT_ID);
        if (StringUtils.isBlank(tenantId)) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "请选择小程序后登录");
        }
        if (StringUtils.isBlank(wxAppletModel.getOpenId())) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "登录用户名必填");
        }
        OpenIdQuery query = new OpenIdQuery();
        query.setOpenId(wxAppletModel.getOpenId());
        ResponseResult<MemberLoginDTO> responseResult = memberLoginClient.queryLoginMemberByOpenId(query);
        if (null == responseResult || null == responseResult.getData()) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "查询会员信息失败");
        }
        return queryMember(tenantId, responseResult.getData());
    }

    /***
     * 封装查询登录用户
     * @param query 参数
     * @return
     */
    private ClientUserDetails queryMember(String tenantId, MemberLoginDTO query) {
        if (null == query) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "会员不存在");
        }
        if (PublishStatusEnum.DISABLE.getValue().equals(query.getPublishStatus())) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "当前会员账号禁止登陆");
        }
        ClientUserDetails clientUserDetails = new ClientUserDetails();
        clientUserDetails.setId(query.getId());
        clientUserDetails.setTenantId(query.getTenantId());
        clientUserDetails.setIndustry(query.getIndustry());
        clientUserDetails.setName(query.getName());
        clientUserDetails.setMobile(query.getPhone());
        clientUserDetails.setTenantId(Integer.valueOf(tenantId));
        clientUserDetails.setUniqueId(query.getUniqueId());
        clientUserDetails.setPassword(query.getUniqueId());
        clientUserDetails.setRegister(StringUtils.isBlank(query.getPhone()));
        List<SimpleGrantedAuthority> roles = new ArrayList<>();
        roles.add(new SimpleGrantedAuthority(LoginRoleEnum.WX_MA.name()));
        roles.add(new SimpleGrantedAuthority(LoginRoleEnum.WX_MA.name()));
        clientUserDetails.setRoles(roles);
        return clientUserDetails;
    }
}
